﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using StackOverflowClient.Events;
using StackOverflowClient.Messages;
using StackOverflowClient.Properties;
using System.Net;

namespace StackOverflowClient
{
    public class StackOverflowClient
    {
        private const int pollingInterval = 1800000;
        private readonly Listner listener = new Listner(pollingInterval);
        private readonly Timer timer = new Timer();
        private readonly Dictionary<Type, MessageEventBase> messageToEvent = new Dictionary<Type, MessageEventBase>();
        private UserDescriptor userDetails;

        #region Events
        public delegate void UserDetailsChnagedHandler(UserDescriptor user);
        public event UserDetailsChnagedHandler userDetailsChanged;

        public delegate void UserReputationChanagedHandler(int oldReputation, int newReputation);
        public event UserReputationChanagedHandler userReputationChanged;
        
        public delegate void UserBadgeChangedHandler(int oldValue, int newValue);
        public event UserBadgeChangedHandler userBadgeNumberChanged;
        #endregion


        public StackOverflowClient()
        {
            messageToEvent.Add(typeof(ReputationChangedMessage), new ReputationUpdatedEvent(this));
            messageToEvent.Add(typeof(NumberOfBadgesChangedMessage), new NumberOfBadgesUpdatedEvent(this));

            timer.Interval = 60000;
            timer.Tick += timer_Tick;
        }

        public string Url { get; set; }


        public IWebProxy Proxy{get;set;}

        public UserDescriptor User
        {
            get { return userDetails; }
            private set
            {
                userDetails = value;
                OnUserDetailsChanged(User);
            }
        }

        public void Start(UserDescriptor userDescription)
        {
            User = listener.GetUserDetails(userDescription);

            listener.Run(new ListnerParams(Url, Proxy));
            timer.Enabled = true;
        }

        public void Stop()
        {
            timer.Enabled = false;
            listener.Abort();
        }

        void timer_Tick(object sender, System.EventArgs e)
        {
            while (listener.MessageQueue.Count > 0)
            {
                MessageBase newMessage = listener.MessageQueue.Dequeue();
                messageToEvent[newMessage.GetType()].RaiseEvent(newMessage);
            }
        }

        internal void OnUserReputationChanged(int oldReputation, int newReputation)
        {
            if (userReputationChanged != null)
            {
                userReputationChanged(oldReputation, newReputation);
            }
        }
        
        internal void OnUserBadgeNumberChanged(int oldBadgeNumber, int newBadgeNumber)
        {
        if (userReputationChanged != null)
            {
                userReputationChanged(oldBadgeNumber, newBadgeNumber);
            }
        }

        internal void OnUserDetailsChanged(UserDescriptor userDescriptor)
        {
            if (userDetailsChanged != null)
            {
                userDetailsChanged(userDescriptor);
            }
        }

        public UserDescriptor IsValid(string userURL)
        {
            return listener.IsValid(userURL, Proxy);
        }
    }
}
